/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/*
 * MainWindow.java
 *
 * Created on May 20, 2012, 1:31:00 AM
 */
package server;
//<editor-fold defaultstate="collapsed" desc=" các thư viện sử dụng">
import java.awt.Component;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.*;
import org.xml.sax.SAXException;



//</editor-fold>
/**
 *
 * @author KingofSpeed
 */
public final class MainWindow extends javax.swing.JFrame {

    //<editor-fold defaultstate="collapsed" desc=" biến toàn cục ">
    private ServerSocket server;
    private InetAddress ipServer;
    public int port = 12345;
    public String linkDatabase = ".\\Database";
    public DefaultListModel listTable;
    public JTable tablePreview;
    public List<DataTable> dataTables;
    public List<Socket> clients;
    ClientAccept clientAccept;
    public Object communicationLock;
    public Object acceptLock;
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" khởi tạo với port cho trước ">
    public MainWindow( int por) {
        
        initComponents();
        port = por;
        listTable = new DefaultListModel();
        tablePreview = new MyJTable(this);
        tablePreview.getTableHeader().setReorderingAllowed(false);
        
        dsTable.setModel(listTable);
        viewTable.getViewport().add(tablePreview);
        
        dataTables= new ArrayList<DataTable>();
        
        LoadTable();
        dsTable.addListSelectionListener(new ListSelectionChanged());
        tablePreview.addKeyListener(new TableKeyListener());
        
        clientAccept = new ClientAccept(this);
        clientAccept.start();
       
        communicationLock = new Object();
        acceptLock = new Object();
        
      
    }
//</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" Code generate từ design  ">
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
    private void initComponents() {

        bCreateTable = new javax.swing.JButton();
        bEditTable = new javax.swing.JButton();
        bDeleteTable = new javax.swing.JButton();
        viewTable = new javax.swing.JScrollPane();
        bDeleteRecord = new javax.swing.JButton();
        bLoad = new javax.swing.JButton();
        bSave = new javax.swing.JButton();
        bAbout = new javax.swing.JButton();
        bRefresh = new javax.swing.JButton();
        jLabel1 = new javax.swing.JLabel();
        bClient = new javax.swing.JButton();
        tbIp = new javax.swing.JTextField();
        jScrollPane1 = new javax.swing.JScrollPane();
        dsTable = new javax.swing.JList();
        bAddRow = new javax.swing.JButton();
        jLabel2 = new javax.swing.JLabel();
        jLabel3 = new javax.swing.JLabel();
        jLabel4 = new javax.swing.JLabel();
        tbPort = new javax.swing.JTextField();
        bRenameTable = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        bCreateTable.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/CreateTableNormal.png"))); // NOI18N
        bCreateTable.setToolTipText("Create New Table");
        bCreateTable.setAlignmentY(0.0F);
        bCreateTable.setBorderPainted(false);
        bCreateTable.setContentAreaFilled(false);
        bCreateTable.setMargin(new java.awt.Insets(0, 0, 0, 0));
        bCreateTable.setMaximumSize(new java.awt.Dimension(75, 75));
        bCreateTable.setMinimumSize(new java.awt.Dimension(50, 50));
        bCreateTable.setPreferredSize(new java.awt.Dimension(60, 60));
        bCreateTable.setVerifyInputWhenFocusTarget(false);
        bCreateTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bCreateTableMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bCreateTableMouseExited(evt);
            }
        });
        bCreateTable.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bCreateTableActionPerformed(evt);
            }
        });

        bEditTable.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/EditTableNormal.png"))); // NOI18N
        bEditTable.setToolTipText("Edit Table");
        bEditTable.setAlignmentY(0.0F);
        bEditTable.setBorderPainted(false);
        bEditTable.setContentAreaFilled(false);
        bEditTable.setMargin(new java.awt.Insets(0, 0, 0, 0));
        bEditTable.setMaximumSize(new java.awt.Dimension(75, 75));
        bEditTable.setMinimumSize(new java.awt.Dimension(50, 50));
        bEditTable.setPreferredSize(new java.awt.Dimension(60, 60));
        bEditTable.setVerifyInputWhenFocusTarget(false);
        bEditTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bEditTableMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bEditTableMouseExited(evt);
            }
        });
        bEditTable.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bEditTableActionPerformed(evt);
            }
        });

        bDeleteTable.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/DeleteTableNormal.png"))); // NOI18N
        bDeleteTable.setToolTipText("Delete Table");
        bDeleteTable.setAlignmentY(0.0F);
        bDeleteTable.setBorderPainted(false);
        bDeleteTable.setContentAreaFilled(false);
        bDeleteTable.setMargin(new java.awt.Insets(0, 0, 0, 0));
        bDeleteTable.setMaximumSize(new java.awt.Dimension(75, 75));
        bDeleteTable.setMinimumSize(new java.awt.Dimension(50, 50));
        bDeleteTable.setPreferredSize(new java.awt.Dimension(60, 60));
        bDeleteTable.setVerifyInputWhenFocusTarget(false);
        bDeleteTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bDeleteTableMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bDeleteTableMouseExited(evt);
            }
        });
        bDeleteTable.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bDeleteTableActionPerformed(evt);
            }
        });

        viewTable.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        viewTable.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
        viewTable.setVerticalScrollBarPolicy(javax.swing.ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
        viewTable.setViewportBorder(javax.swing.BorderFactory.createEtchedBorder());

        bDeleteRecord.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/DeleteRecordNormal.png"))); // NOI18N
        bDeleteRecord.setToolTipText("Delete Rows");
        bDeleteRecord.setContentAreaFilled(false);
        bDeleteRecord.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bDeleteRecordMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bDeleteRecordMouseExited(evt);
            }
        });
        bDeleteRecord.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bDeleteRecordActionPerformed(evt);
            }
        });

        bLoad.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/LoadNormal.png"))); // NOI18N
        bLoad.setToolTipText("Load Database");
        bLoad.setContentAreaFilled(false);
        bLoad.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bLoadMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bLoadMouseExited(evt);
            }
        });
        bLoad.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bLoadActionPerformed(evt);
            }
        });

        bSave.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/SaveNormal.png"))); // NOI18N
        bSave.setToolTipText("Save Database");
        bSave.setContentAreaFilled(false);
        bSave.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bSaveMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bSaveMouseExited(evt);
            }
        });
        bSave.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bSaveActionPerformed(evt);
            }
        });

        bAbout.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/AboutNormal.png"))); // NOI18N
        bAbout.setToolTipText("About");
        bAbout.setContentAreaFilled(false);
        bAbout.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bAboutMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bAboutMouseExited(evt);
            }
        });
        bAbout.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bAboutActionPerformed(evt);
            }
        });

        bRefresh.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/RefreshNormal.png"))); // NOI18N
        bRefresh.setToolTipText("Refresh Server");
        bRefresh.setContentAreaFilled(false);
        bRefresh.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bRefreshMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bRefreshMouseExited(evt);
            }
        });
        bRefresh.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bRefreshActionPerformed(evt);
            }
        });

        jLabel1.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        jLabel1.setText("IP Server :");

        bClient.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/AccountsNormal.png"))); // NOI18N
        bClient.setToolTipText("Client Connected");
        bClient.setContentAreaFilled(false);
        bClient.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bClientMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bClientMouseExited(evt);
            }
        });
        bClient.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bClientActionPerformed(evt);
            }
        });

        tbIp.setEditable(false);
        tbIp.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N

        dsTable.setBackground(new java.awt.Color(240, 240, 240));
        dsTable.setBorder(javax.swing.BorderFactory.createEtchedBorder());
        dsTable.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        jScrollPane1.setViewportView(dsTable);

        bAddRow.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/AddColumnNormal.png"))); // NOI18N
        bAddRow.setToolTipText("Add Row");
        bAddRow.setContentAreaFilled(false);
        bAddRow.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bAddRowMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bAddRowMouseExited(evt);
            }
        });
        bAddRow.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bAddRowActionPerformed(evt);
            }
        });

        jLabel2.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jLabel2.setText("List Tables:");

        jLabel3.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N
        jLabel3.setText("Data Table :");

        jLabel4.setFont(new java.awt.Font("Tahoma", 0, 18)); // NOI18N
        jLabel4.setText("Port :");

        tbPort.setEditable(false);
        tbPort.setFont(new java.awt.Font("Tahoma", 0, 14)); // NOI18N

        bRenameTable.setIcon(new javax.swing.ImageIcon(getClass().getResource("/SourceImage/RenameNormal.png"))); // NOI18N
        bRenameTable.setToolTipText("Rename table");
        bRenameTable.setContentAreaFilled(false);
        bRenameTable.addMouseListener(new java.awt.event.MouseAdapter() {
            public void mouseEntered(java.awt.event.MouseEvent evt) {
                bRenameTableMouseEntered(evt);
            }
            public void mouseExited(java.awt.event.MouseEvent evt) {
                bRenameTableMouseExited(evt);
            }
        });
        bRenameTable.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                bRenameTableActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(bCreateTable, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bDeleteTable, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bEditTable, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bRenameTable, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bDeleteRecord, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bAddRow, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bLoad, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bSave, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bClient, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bAbout, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(bRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel1)
                    .addComponent(jLabel4))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING, false)
                    .addComponent(tbIp)
                    .addComponent(tbPort, javax.swing.GroupLayout.PREFERRED_SIZE, 150, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 242, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addGroup(layout.createSequentialGroup()
                        .addGap(36, 36, 36)
                        .addComponent(jLabel2)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(viewTable, javax.swing.GroupLayout.DEFAULT_SIZE, 752, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 108, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 0, Short.MAX_VALUE))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
                    .addGroup(layout.createSequentialGroup()
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel1)
                            .addComponent(tbIp, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                        .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                            .addComponent(jLabel4)
                            .addComponent(tbPort, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)))
                    .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                        .addComponent(bCreateTable, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bEditTable, javax.swing.GroupLayout.DEFAULT_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bDeleteTable, javax.swing.GroupLayout.DEFAULT_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bRenameTable, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bDeleteRecord, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bLoad, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bSave, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bAbout, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bRefresh, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bClient, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addComponent(bAddRow, javax.swing.GroupLayout.PREFERRED_SIZE, 60, javax.swing.GroupLayout.PREFERRED_SIZE)))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jLabel3)
                    .addComponent(jLabel2))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 522, Short.MAX_VALUE)
                    .addComponent(viewTable)))
        );

        pack();
    }// </editor-fold>//GEN-END:initComponents

    private void bCreateTableMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bCreateTableMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/CreateTableClick.png"));
        bCreateTable.setIcon(ii);
    }//GEN-LAST:event_bCreateTableMouseEntered

    private void bCreateTableMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bCreateTableMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/CreateTableNormal.png"));
        bCreateTable.setIcon(ii);
    }//GEN-LAST:event_bCreateTableMouseExited

    private void bDeleteTableMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bDeleteTableMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/DeleteTableClick.png"));
        bDeleteTable.setIcon(ii);
    }//GEN-LAST:event_bDeleteTableMouseEntered

    private void bDeleteTableMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bDeleteTableMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/DeleteTableNormal.png"));
        bDeleteTable.setIcon(ii);
    }//GEN-LAST:event_bDeleteTableMouseExited

    private void bEditTableMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bEditTableMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/EditTableClick.png"));
        bEditTable.setIcon(ii);
    }//GEN-LAST:event_bEditTableMouseEntered

    private void bEditTableMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bEditTableMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/EditTableNormal.png"));
        bEditTable.setIcon(ii);
    }//GEN-LAST:event_bEditTableMouseExited

    private void bCreateTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bCreateTableActionPerformed
        ArrayList<String> tam = new ArrayList<String>();
        for ( int i = 0; i < dataTables.size(); i++ )
        {
            tam.add( dataTables.get(i).getName());
        }
        String name = MyJOptionPane.showInputDialog("Nhập Tên Bảng", "Tên Bảng", "", tam);
        if ( name.equals(""))
        {
            return;
        }
        CreateTableForm createTable;
        createTable = new CreateTableForm( this, 0,-1, name);
        createTable.show();
    }//GEN-LAST:event_bCreateTableActionPerformed

    private void bDeleteRecordMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bDeleteRecordMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/DeleteRecordClick.png"));
        bDeleteRecord.setIcon(ii);
    }//GEN-LAST:event_bDeleteRecordMouseEntered

    private void bDeleteRecordMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bDeleteRecordMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/DeleteRecordNormal.png"));
        bDeleteRecord.setIcon(ii);
    }//GEN-LAST:event_bDeleteRecordMouseExited

    private void bLoadMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bLoadMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/LoadClick.png"));
        bLoad.setIcon(ii);
    }//GEN-LAST:event_bLoadMouseEntered

    private void bLoadMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bLoadMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/LoadNormal.png"));
        bLoad.setIcon(ii);
    }//GEN-LAST:event_bLoadMouseExited

    private void bSaveMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bSaveMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/SaveClick.png"));
        bSave.setIcon(ii);
    }//GEN-LAST:event_bSaveMouseEntered

    private void bSaveMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bSaveMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/SaveNormal.png"));
        bSave.setIcon(ii);
    }//GEN-LAST:event_bSaveMouseExited

    private void bAboutMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bAboutMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/AboutClick.png"));
        bAbout.setIcon(ii);
    }//GEN-LAST:event_bAboutMouseEntered

    private void bAboutMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bAboutMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/AboutNormal.png"));
        bAbout.setIcon(ii);
    }//GEN-LAST:event_bAboutMouseExited

    private void bRefreshMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bRefreshMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/RefreshClick.png"));
        bRefresh.setIcon(ii);
    }//GEN-LAST:event_bRefreshMouseEntered

    private void bRefreshMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bRefreshMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/RefreshNormal.png"));
        bRefresh.setIcon(ii);
    }//GEN-LAST:event_bRefreshMouseExited

    private void bClientMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bClientMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/AccountsClick.png"));
        bClient.setIcon(ii);
    }//GEN-LAST:event_bClientMouseEntered

    private void bClientMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bClientMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/AccountsNormal.png"));
        bClient.setIcon(ii);
    }//GEN-LAST:event_bClientMouseExited

    private void bRefreshActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bRefreshActionPerformed
        this.StartServer();
        this.LoadTable();
        this.ChangeIcon();
        if ( listTable.size() > 0 )
            dsTable.setSelectedIndex(0);
    }//GEN-LAST:event_bRefreshActionPerformed

    private void bAddRowMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bAddRowMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/AddColumnClick.png"));
        bAddRow.setIcon(ii);
    }//GEN-LAST:event_bAddRowMouseEntered

    private void bAddRowMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bAddRowMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/AddColumnNormal.png"));
        bAddRow.setIcon(ii);
    }//GEN-LAST:event_bAddRowMouseExited

    private void bAddRowActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bAddRowActionPerformed
        AddNewRows();
    }//GEN-LAST:event_bAddRowActionPerformed

    private void bDeleteRecordActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bDeleteRecordActionPerformed
        DeleteRows( tablePreview.getSelectedRow() );
    }//GEN-LAST:event_bDeleteRecordActionPerformed

    private void bAboutActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bAboutActionPerformed
//            ToolSQL toolSQL = new ToolSQL(this);
//            Document doc = toolSQL.Test();
//            if ( doc != null )
//            {
//            try
//            {
//                TransformerFactory transfac = TransformerFactory.newInstance();
//                Transformer trans = transfac.newTransformer();
//                trans.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes");
//                trans.setOutputProperty( OutputKeys.INDENT, "yes");
//                
//                File file = new File("D:\\result.xml");
//                StreamResult res = new StreamResult(file);
//                DOMSource source = new DOMSource(doc);
//                trans.transform(source, res);
//            }
//            catch ( Exception ex) {  }
//            }
        Info info = new Info();
        info.show();
    }//GEN-LAST:event_bAboutActionPerformed

    private void bClientActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bClientActionPerformed
        ListClientConnected listClientConnected = new ListClientConnected(this);
        listClientConnected.show();
    }//GEN-LAST:event_bClientActionPerformed

    private void bSaveActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bSaveActionPerformed
        SaveData();
        
    }//GEN-LAST:event_bSaveActionPerformed

    private void bRenameTableMouseEntered(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bRenameTableMouseEntered
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/RenameClick.png"));
        bRenameTable.setIcon(ii);
    }//GEN-LAST:event_bRenameTableMouseEntered

    private void bRenameTableMouseExited(java.awt.event.MouseEvent evt) {//GEN-FIRST:event_bRenameTableMouseExited
        ImageIcon ii = new ImageIcon(this.getClass().getResource("/SourceImage/RenameNormal.png"));
        bRenameTable.setIcon(ii);
    }//GEN-LAST:event_bRenameTableMouseExited

    private void bRenameTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bRenameTableActionPerformed
       RenameTable();
    }//GEN-LAST:event_bRenameTableActionPerformed

    private void bDeleteTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bDeleteTableActionPerformed
        DeleteTable();
    }//GEN-LAST:event_bDeleteTableActionPerformed

    private void bEditTableActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bEditTableActionPerformed
        
        try
        {   
            int index = dsTable.getSelectedIndex();
            if ( index < 0)
                return;
            CreateTableForm createTable;
            createTable = new CreateTableForm( this, 1,index, dataTables.get(index).getName());
            createTable.show();
        }
        catch ( Exception ex ){ ShowMessageBox( ex.toString(), "");}
    }//GEN-LAST:event_bEditTableActionPerformed

    private void bLoadActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_bLoadActionPerformed
        LoadData();
    }//GEN-LAST:event_bLoadActionPerformed
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" xử lí khi muốn load data từ một thư mục khác ">
    public void LoadData()
    {
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            if ( fileChooser.showDialog( this ," Load Dữ Liệu, Chọn Thư Mục Chứa Data") == JFileChooser.APPROVE_OPTION )
            {
                linkDatabase = fileChooser.getSelectedFile().getPath();
                try 
                {
                    LoadTable();
                } 
                catch ( Exception ex) 
                {
                    ShowMessageBox( "Không Thể Load DataBase :" + ex.toString(),"Error" );  
                }
            }
    }//</editor-fold>
    
    //<editor-fold defaultstate="collapsed" desc=" xủa lý khi muốn save data ra một thư mục khác ">
    public void SaveData()
    {
            JFileChooser fileChooser = new JFileChooser();
            fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
            if ( fileChooser.showDialog( this ,"Lưu Dữ Liệu, Chọn Thư Mục Chứa Data") == JFileChooser.APPROVE_OPTION )
            {
                linkDatabase = fileChooser.getSelectedFile().getPath();
                try 
                {
                    for ( int i = 0; i < dataTables.size(); i++)
                    {
                        dataTables.get(i).SaveData();
                    }
                    LoadTable();
                } 
                catch ( Exception ex) 
                {
                    ShowMessageBox( "Không Thể Lưu DataBase :" + ex.toString(),"Error" );  
                }
            }
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" xóa một bảng ( xóa một file xml ) kiểm ra khóa ngoại trước khi xóa ">
    public void DeleteTable()
    {
        try
        {
            int n = dsTable.getSelectedIndex();
            if ( n < 0 )
                return;
            if ( JOptionPane.showConfirmDialog(null, "Bạn Cóc Chắc Muốn Xóa Bảng Này Không, Xóa Rồi Không Thể Khôi Phục"
                    ,"Xóa Bảng", JOptionPane.OK_CANCEL_OPTION ) == JOptionPane.OK_OPTION )
            {
                    ToolSQL toolSQL = new ToolSQL(this);
                    if ( toolSQL.CanDelete(n))
                    {
                        new File( linkDatabase + "\\" + dsTable.getSelectedValue() + ".xml").delete();
                        LoadTable();
                    }
            }
        }
        catch( Exception ex ){ ShowMessageBox( ex.toString(), "");}
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" Xử lí khi đổi tên bảng ">
    public void RenameTable()
    {
        try
        {
            int index = dsTable.getSelectedIndex();
            if ( index < 0 )
                return ;
            else
            {
                String oldName = dataTables.get(index).getName();
                ArrayList<String> tam = new ArrayList<String>();
                for( int i = 0; i < dataTables.size(); i++ )
                {
                    if ( i != index )
                        tam.add(dataTables.get(i).getName());
                }
                String result = MyJOptionPane.showInputDialog("Đổi Tên Table", "Tên Mới", oldName, tam);
                if ( !result.equals(oldName)  )
                {
                    try
                    {
                        ToolSQL toolSQL = new ToolSQL(this);
                        if ( toolSQL.RenameTable(oldName, result))
                        {
                            
                            dataTables.get(index).setName(result);
                            dataTables.get(toolSQL.NameToIndex(result)).SaveTableName(oldName);
                            LoadTable();
                        }
                    }
                    catch ( Exception ex){ ShowMessageBox("Đổi Tên Thất Bại", "Error"); }
                        
                }
            }
        }
        catch( Exception ex ){}
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" xử lý khi muốn xóa một record, kiểm tra các ràng buộc ">
    public void DeleteRows( int index )
    {
        try
        {
            int rIndex = tablePreview.getSelectedRow();
            if ( rIndex == -1 )
                rIndex = tablePreview.getRowCount() - 1;
            int tIndex = -1;
            ToolSQL toolSQL = new ToolSQL(this);
            String tName = String.valueOf(dsTable.getSelectedValue());
            tIndex = toolSQL.NameToIndex(tName);
            if ( tIndex < 0 )
                    return;
            if ( rIndex != -1 )
            { 
                tIndex = toolSQL.NameToIndex(tName);
                for ( int i = 0; i < dataTables.get(tIndex).getnColumn(); i++ )
                {
                    if ( !toolSQL.CheckForeignKeyFrom( tName, rIndex, i))
                    {
                        ShowMessageBox("Vi Phạm, có khóa ngoại trỏ đến bảng này, hãy xóa các khóa ngoại trước", "Error");
                        return;
                    }
                }
            }
            dataTables.get(tIndex).getModel().removeRow(rIndex); 
        }
        catch ( Exception ex ){}
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" xử lí khi muốn add một record , kiểm tra các ràng buộc ">
    public void AddNewRows()
    {
        int rIndex = tablePreview.getEditingRow();
        
        if ( rIndex == -1 )
            rIndex = tablePreview.getRowCount() - 1;
        if ( rIndex != -1 )
        { 
            
            ToolSQL toolSQL = new ToolSQL(this);
            int tIndex = toolSQL.NameToIndex(String.valueOf(dsTable.getSelectedValue()));
            for ( int i = 0; i < dataTables.get(tIndex).getnColumn(); i++ )
            {
                String v = String.valueOf( dataTables.get(tIndex).getModel().getValueAt(rIndex, i));
                if ( dataTables.get(tIndex).getColumns().get(i).getType().equals("Number") 
                        && !toolSQL.CheckIsNum(v) )
                {
                    ShowMessageBox("Lỗi Sai Kiểu Dữ Liệu", "Error");
                    return;
                }
                
                if ( !dataTables.get(tIndex).CheckNotNull(rIndex, i) )
                {
                    ShowMessageBox("Lỗi Cột "+ dataTables.get(tIndex).getColumns().get(i).getTitle() + " Không Cho Để Trống", "Error");
                    return;
                }
               
                if ( !dataTables.get(tIndex).CheckPrimaryKey(rIndex, i))
                {
                    ShowMessageBox("Nội Dung Vi Phạm Lỗi Trùng Lặp Của Khóa Chính", "Error");
                    return;
                }
                
                if ( !toolSQL.CheckForiegnKeyTo(String.valueOf(dsTable.getSelectedValue()), rIndex, i))
                {
                    ShowMessageBox("Vi Phạm Lỗi Khóa Ngoại ","Error");
                    return;
                }
                 
            }
        }
         
            ArrayList data = new ArrayList();
            for ( int i = 0;  i < dataTables.get(dsTable.getSelectedIndex()).getnColumn(); i++ )
            {
                data.add("");
            }
            dataTables.get(dsTable.getSelectedIndex()).getModel().addRow(data.toArray());   
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" khởi tạo server với port có sẵn ">
    public boolean StartServer()
    {
        try
        {
            if (server != null )
                server.close();
            ipServer = InetAddress.getLocalHost();
            tbIp.setText( ipServer.getHostAddress().toString() );
            server = new ServerSocket(port);
            File f = new File( linkDatabase );
            clients = new ArrayList<Socket>();
            tbPort.setText(String.valueOf(port));
            if ( !f.exists() )
            {
                return  new File( linkDatabase ).mkdir();
            }
            return true;
        }
        catch(Exception e){
            
            ShowMessageBox("Server Can Not Start ! "+ e.toString(), "Error");
            return false;
        }
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" hàm hiển thị các loại thông báo ">
     public void ShowMessageBox ( String ms , String l )
    {
        if ( "Error".equals(l))
             JOptionPane.showMessageDialog( this, ms, "Lỗi", JOptionPane.ERROR_MESSAGE);
        else if ( "Success".equals(l))
            JOptionPane.showMessageDialog( this, ms, "Thành Công", JOptionPane.INFORMATION_MESSAGE);
        else
            JOptionPane.showMessageDialog( this, ms, "Thông Báo", JOptionPane.PLAIN_MESSAGE);
    }
     //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" hàm main này để nhập port bước đầu rồi mới chạy ct">
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(MainWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                int p = MyJOptionPane.showInputPortDialog();
                if ( p != 0 )
                {
                    MainWindow main = new MainWindow( p );
                    if ( main.StartServer() == true )
                        main.setVisible(true);
                    else
                        main.dispose();
                }
            }
        });
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" biến generate từ design ">
    // Variables declaration - do not modify//GEN-BEGIN:variables
    public javax.swing.JButton bAbout;
    public javax.swing.JButton bAddRow;
    public javax.swing.JButton bClient;
    public javax.swing.JButton bCreateTable;
    public javax.swing.JButton bDeleteRecord;
    public javax.swing.JButton bDeleteTable;
    public javax.swing.JButton bEditTable;
    public javax.swing.JButton bLoad;
    public javax.swing.JButton bRefresh;
    private javax.swing.JButton bRenameTable;
    public javax.swing.JButton bSave;
    public javax.swing.JList dsTable;
    private javax.swing.JLabel jLabel1;
    private javax.swing.JLabel jLabel2;
    private javax.swing.JLabel jLabel3;
    private javax.swing.JLabel jLabel4;
    private javax.swing.JScrollPane jScrollPane1;
    public javax.swing.JTextField tbIp;
    private javax.swing.JTextField tbPort;
    private javax.swing.JScrollPane viewTable;
    // End of variables declaration//GEN-END:variables
//</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" load bảng từ các file xml trong database, tên bảng = tên file ">
    public void LoadTable()
    {
        dataTables= new ArrayList<DataTable>();
        listTable = new DefaultListModel();
        DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance();
        DocumentBuilder documentBuilder = null;
        Document document;
        File folder = new File( linkDatabase );
        File []listFiles = folder.listFiles();
       
        for ( int i = 0; i < listFiles.length; i++ )
        {
            if ( listFiles[i].isFile())
            {
                String name = listFiles[i].getName();
                if ( name.endsWith(".xml") || name.endsWith(".XML"))
                {
                    try
                    {
                        documentBuilder = builderFactory.newDocumentBuilder();
                        try 
                        {
                            document = documentBuilder.parse(new File( linkDatabase + "\\" + name ));
                             
                            document.getDocumentElement().normalize();
                            
                            NodeList root = document.getElementsByTagName("Table");
                            listTable.addElement(root.item(0).getAttributes().getNamedItem("name").getNodeValue());
                            DataTable tam = new DataTable(this);
                            
                            tam.LoadData(linkDatabase + "\\" + name);
                            
                            dataTables.add(tam);
                        } 
                        catch (SAXException ex) 
                        {
                            i++;
                        } 
                        catch (IOException ex) 
                        {
                             i++;
                        }
                    }
                    catch( ParserConfigurationException ex )
                    {

                    }
                }
            }
        }
        dsTable.setModel(listTable);
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" thay đổi icon cột tương ứng với các khóa mà cột này giữ">
    public void ChangeIcon()
    {
        try
            {
                int index = dsTable.getSelectedIndex();
                tablePreview.setModel(dataTables.get(index).getModel());
                Icon ipk = new ImageIcon(this.getClass().getResource("/SourceImage/IconPrimaryKey.png"));
                Icon ipf = new ImageIcon(this.getClass().getResource("/SourceImage/IconForeignKey.png"));
                Icon ipkf = new ImageIcon(this.getClass().getResource("/SourceImage/IconPrimaryForeignKey.png"));
                TableCellRenderer render = new JComponentTableCellRenderer(this);
                
                for ( int i = 0; i < dataTables.get(index).getListColumn().size(); i++  )
                {
                    try
                    {
                       if ( dataTables.get(index).getListColumn().get(i).isIsPrimary() == true 
                                && dataTables.get(index).getListColumn().get(i).isIsHaveForeignKey() == true )
                        {
                           JLabel label = new JLabel( dataTables.get(index).getModel().getColumnName(i),
                                    ipkf, JLabel.CENTER);
                            label.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
                            tablePreview.getColumnModel().getColumn(i).setHeaderRenderer(render);
                            tablePreview.getColumnModel().getColumn(i).setHeaderValue(label);
                        }
                        else if ( dataTables.get(index).getListColumn().get(i).isIsPrimary() == true 
                                && dataTables.get(index).getListColumn().get(i).isIsHaveForeignKey() == false )
                        {
                            JLabel label = new JLabel( dataTables.get(index).getModel().getColumnName(i),
                                    ipk, JLabel.CENTER);
                            label.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
                            tablePreview.getTableHeader().getColumnModel().getColumn(i).setHeaderRenderer(render);
                            tablePreview.getColumnModel().getColumn(i).setHeaderValue(label);
                        }
                        else if ( dataTables.get(index).getListColumn().get(i).isIsPrimary() == false 
                                && dataTables.get(index).getListColumn().get(i).isIsHaveForeignKey() == true )
                        {
                           JLabel label = new JLabel( dataTables.get(index).getModel().getColumnName(i),
                                    ipf, JLabel.CENTER);
                            label.setBorder(UIManager.getBorder("TableHeader.cellBorder"));
                            tablePreview.getTableHeader().getColumnModel().getColumn(i).setHeaderRenderer(render);
                            tablePreview.getColumnModel().getColumn(i).setHeaderValue(label);
                        }
                        
                    }
                    catch ( Exception ex ){}
                }
                
            }
            catch ( Exception ex )
            {
            }
            tablePreview.repaint();
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" xử lý sự kiện click chọn bảng bên trái ">
    class ListSelectionChanged implements ListSelectionListener
    {
        @Override
        public void valueChanged(ListSelectionEvent e)
        {
            ChangeIcon();
            tablePreview.repaint();
        }
    }
    //<editor-fold defaultstate="collapsed" desckiejenxuwr lý sự kiện nhấn enter thêm dòng mới ">
    class TableKeyListener extends KeyAdapter
    {
       @Override
       public void keyPressed( KeyEvent e )
       {
           if ( e.getKeyCode() == KeyEvent.VK_ENTER )
           {
               try
               {
                   AddNewRows();
               }
               catch ( Exception ex ){}
           }
       }
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" class để kiểm tra mỗi khi có dữ liệu mới nhập vào">
    public class JComponentTableCellRenderer implements TableCellRenderer
    {
        MainWindow parent;
        public JComponentTableCellRenderer( MainWindow _main)
        {
            super();
            parent = _main;
        }
        @Override
        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            return (JComponent)value;
        }
        public boolean stopCellEditing() 
        {
        try 
        {
            {
            int rIndex = tablePreview.getEditingRow();
            if ( rIndex != -1 )
            { 
                ToolSQL toolSQL = new ToolSQL(parent);
                int tIndex = toolSQL.NameToIndex(String.valueOf(dsTable.getSelectedValue()));
                for ( int i = 0; i < dataTables.get(tIndex).getnColumn(); i++ )
                {
                    
                    String v = String.valueOf( dataTables.get(tIndex).getModel().getValueAt(rIndex, i));
                        if ( dataTables.get(tIndex).getColumns().get(i).getType().equals("Number") 
                                && !toolSQL.CheckIsNum(v) )
                        {
                            ShowMessageBox("Lỗi Sai Kiểu Dữ Liệu", "Error");
                            return false;
                        }
                        if ( dataTables.get(tIndex).getColumns().get(i).getType().equals("String") 
                                && !toolSQL.CheckIsString(v) )
                        {
                            ShowMessageBox("Lỗi Dữ Liệu Chứa Kĩ Tự Cấm", "Error");
                            return false;
                        }
                    if ( !dataTables.get(tIndex).CheckNotNull(rIndex, i) )
                {
                    ShowMessageBox("Lỗi Cột "+ dataTables.get(tIndex).getColumns().get(i).getTitle() + " Không Cho Để Trống", "Error");
                    return false;
                }
                if ( !dataTables.get(tIndex).CheckPrimaryKey(rIndex, i))
                {
                    ShowMessageBox("Nội Dung Vi Phạm Lỗi Trùng Lặp Của Khóa Chính", "Error");
                    return false;
                }
                if ( !toolSQL.CheckForiegnKeyTo(String.valueOf(dsTable.getSelectedValue()), rIndex, i))
                {
                    ShowMessageBox("Vi Phạm Lỗi Khóa Ngoại ","Error");
                    return false;
                }
                }
            }
                ArrayList data = new ArrayList();
                for ( int i = 0;  i < dataTables.get(dsTable.getSelectedIndex()).getnColumn(); i++ )
                {
                    data.add("");
                }
                dataTables.get(dsTable.getSelectedIndex()).getModel().addRow(data.toArray());  
            }
            return true;
        }
        catch (Exception e) {
            return false;
        }
  }    
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" thread lắng nghe tất cả các client kết nối ">
    public class ClientAccept extends Thread implements Runnable
    {
        MainWindow parent;
        public ClientAccept( MainWindow main )
        {
            parent = main;
        }
        @Override
        public void run() 
        {
            while ( true )
                {
                    synchronized(acceptLock)
                    {
                        try 
                        {
                            Socket client = server.accept();
                            clients.add(client);
                            
                            Communication communication = new Communication(client, parent);
                            communication.start();
                        } 
                        catch( Exception e )
                        {       
                        }
                    }
                }
        }
    
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" thread giao tiếp giữa client và server ">
    public class Communication extends Thread implements Runnable
    {
        Socket client;
        
        MainWindow parent ;
        public Communication(Socket _client , MainWindow _main) throws IOException
        {
            super();
            parent = _main;
                client = _client;
        }
        @Override
        public void run() 
        {
            while ( true )
                {
                    synchronized(communicationLock)
                    {
                        try 
                        {
                            ObjectInputStream in;
                            ObjectOutputStream out;
                            in = new ObjectInputStream( client.getInputStream());
                            out = new ObjectOutputStream( client.getOutputStream());
                            ToolSQL toolSQL = new ToolSQL( parent);
                            Document doc = (Document)in.readObject();
                          
//                            TransformerFactory transfac = TransformerFactory.newInstance();
//                            Transformer trans = transfac.newTransformer();
//                            trans.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes");
//                            trans.setOutputProperty( OutputKeys.INDENT, "yes");
//
//                            File file = new File("D:\\recieve.xml");
//                            StreamResult res = new StreamResult(file);
//                            DOMSource source = new DOMSource(doc);
//                            trans.transform(source, res);
               
                            Document result = toolSQL.Annalyze(doc);
                            

//                            trans.setOutputProperty( OutputKeys.OMIT_XML_DECLARATION, "yes");
//                            trans.setOutputProperty( OutputKeys.INDENT, "yes");
//
//                            file = new File("D:\\result.xml");
//                            res = new StreamResult(file);
//                            source = new DOMSource(result);
//                            trans.transform(source, res);
                            
                            out.writeObject(result);
                        } 
                        catch( Exception e )
                        {       
                        }
                    }
                }
        }
    
    }
    //</editor-fold>
    //<editor-fold defaultstate="collapsed" desc=" xử lí kiểm tra dữ liệu mỗi khi click chọn record khác ">
    class MyJTable extends JTable
    {
        public MainWindow parent;
        public MyJTable( MainWindow _main)
        {
            super();
            parent = _main;
        }
        public void changeSelection( int rowIndex, int columnIndex, boolean toggle, boolean extend )
        {
            int rIndex =  getSelectedRow() ;
            if ( rIndex <  0)
            {
                super.changeSelection(rowIndex, columnIndex, toggle, extend);
                return;
            }
            if ( rIndex != rowIndex )
            {
                 
                if ( rIndex != -1 )
                { 
                    ToolSQL toolSQL = new ToolSQL(parent);
                    String tName = String.valueOf(dsTable.getSelectedValue());
                    int tIndex = toolSQL.NameToIndex(tName);
                    for ( int i = 0; i < dataTables.get(tIndex).getnColumn(); i++ )
                    {
                        String v = String.valueOf( dataTables.get(tIndex).getModel().getValueAt(rIndex, i));
                        if ( dataTables.get(tIndex).getColumns().get(i).getType().equals("Number") 
                                && !toolSQL.CheckIsNum(v) )
                        {
                            ShowMessageBox("Lỗi Sai Kiểu Dữ Liệu", "Error");
                            return;
                        }
                       if ( !dataTables.get(tIndex).CheckNotNull(rIndex, i) )
                        {
                            ShowMessageBox("Lỗi Cột "+ dataTables.get(tIndex).getColumns().get(i).getTitle() + " Không Cho Để Trống", "Error");
                            return;
                        }
                        if ( !dataTables.get(tIndex).CheckPrimaryKey(rIndex, i))
                        {
                            ShowMessageBox("Nội Dung Vi Phạm Lỗi Trùng Lặp Của Khóa Chính", "Error");
                            return;
                        }
                        if ( !toolSQL.CheckForiegnKeyTo(String.valueOf(dsTable.getSelectedValue()), rIndex, i))
                        {
                            ShowMessageBox("Vi Phạm Lỗi Khóa Ngoại ","Error");
                            return;
                        }
                    }
                }
            }
            super.changeSelection(rowIndex, columnIndex, toggle, extend);
        }
    }
    //</editor-fold>
}
